﻿namespace Resonator.Web
{
	using System;
	using System.Reflection;
	using System.Web;
	using Castle.ActiveRecord;
	using Castle.ActiveRecord.Framework;
	using Castle.ActiveRecord.Framework.Config;
	using Castle.Core;
	using Castle.MonoRail.Framework;
	using Castle.MonoRail.WindsorExtension;
	using Castle.Windsor;
	using NHibernate;
	using NHibernate.Cfg;
	using NHibernate.Search.Engine;
	using NHibernate.Search.Impl;
	using Resonator.Domain.Models;

	public class Global : HttpApplication, IContainerAccessor
	{
		private static WindsorContainer _container;

		public static IWindsorContainer Container
		{
			get { return _container; }
		}

		IWindsorContainer IContainerAccessor.Container
		{
			get { return Container; }
		}

		protected void Application_Start(object sender, EventArgs e)
		{
			InitializeWindsor();
			InitializeActiveRecord();
			InitializeLucene();
		}

		protected void Application_Error(object sender, EventArgs e)
		{
			Exception exc = Server.GetLastError();
		}

		protected static void InitializeWindsor()
		{
			if( _container == null )
			{
				_container = new WindsorContainer();
				_container.AddFacility( "MonoRailFacility", new MonoRailFacility() );

				Type[] controllerTypes = Assembly.GetExecutingAssembly().GetTypes();
				foreach( Type type in controllerTypes )
				{
					if( typeof( IController ).IsAssignableFrom( type ) )
					{
						_container.AddComponentLifeStyle( type.Name, type, LifestyleType.Transient );
					}
				}

				Type[] classTypes = Assembly.Load( "Resonator.Core" ).GetTypes();
				foreach( Type classType in classTypes )
				{
					if( classType.Namespace.IndexOf( "Services" ) < 0 )
					{
						continue;
					}
					if( classType.GetInterfaces().Length == 0 )
					{
						continue;
					}

					Type serviceType = classType.GetInterfaces()[0];
					if( serviceType.IsGenericType )
					{
						serviceType = serviceType.GetGenericTypeDefinition();
					}

					_container.AddComponentLifeStyle( classType.FullName, classType, LifestyleType.Transient );
					_container.AddComponentLifeStyle( string.Concat( serviceType.FullName, "+", classType.FullName ), serviceType, classType, LifestyleType.Transient );
				}
			}
		}

		protected static void InitializeActiveRecord()
		{
			ActiveRecordStarter.ResetInitializationFlag();
			ActiveRecordStarter.Initialize( typeof( ResonatorModel ).Assembly, ActiveRecordSectionHandler.Instance );
		}

		protected static void InitializeLucene()
		{
			ISessionFactoryHolder holder = ActiveRecordMediator.GetSessionFactoryHolder();
			Configuration configuration = holder.GetConfiguration( typeof( ActiveRecordBase ) );
			ISessionFactory sessionFactory = holder.GetSessionFactory( typeof( ActiveRecordBase ) );
			SearchFactory.Initialize( configuration, sessionFactory );
			InterceptorFactory.Create = delegate { return new SearchInterceptor(); };
		}
	}
}